import React, { useCallback, useEffect, useMemo, useState } from 'react'
import {
  Activity,
  AlertTriangle,
  CheckCircle2,
  Clock,
  Download,
  Filter,
  Mail,
  RefreshCw,
  Search,
  ShieldCheck,
  Target,
  Users,
} from 'lucide-react'
import { Card, Button, Input, Modal } from '@/components'
import {
  auditLogAPI,
  AuditLogListResponse,
  AuditLogRecord,
  AuditLogStats,
} from '@/utils/api'

interface Filters {
  module: string
  operationType: string
  operatorKeyword: string
  targetType: string
  targetKeyword: string
  operatorRole: string
  resultStatus: string
  riskLevel: string
  startTime: string
  endTime: string
  onlyUnread: boolean
  onlyAbnormal: boolean
  viewerDepartments: string
}

const defaultFilters: Filters = {
  module: 'all',
  operationType: 'all',
  operatorKeyword: '',
  targetType: 'all',
  targetKeyword: '',
  operatorRole: 'all',
  resultStatus: 'all',
  riskLevel: 'all',
  startTime: '',
  endTime: '',
  onlyUnread: false,
  onlyAbnormal: false,
  viewerDepartments: '',
}

const riskLevelStyles: Record<string, string> = {
  low: 'bg-emerald-50 text-emerald-600 border border-emerald-200',
  medium: 'bg-amber-50 text-amber-600 border border-amber-200',
  high: 'bg-red-50 text-red-600 border border-red-200',
}

const resultStatusStyles: Record<'success' | 'failure', string> = {
  success: 'text-emerald-600',
  failure: 'text-red-600',
}

const operationTypeLabels: Record<string, string> = {
  create: '新增',
  update: '修改',
  delete: '删除',
  review: '审核',
  export: '导出',
  import: '导入',
  config: '配置',
  login: '登录',
  other: '其他',
}

const formatDateTime = (value?: string) => {
  if (!value) return '--'
  const date = new Date(value)
  if (Number.isNaN(date.getTime())) return value

  return new Intl.DateTimeFormat('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
  }).format(date)
}

const stringifyData = (data?: Record<string, unknown> | null) => {
  if (!data) return ''
  try {
    return JSON.stringify(data, null, 2)
  } catch (error) {
    console.warn('无法格式化数据', error)
    return String(data)
  }
}

const AuditLog: React.FC = () => {
  const [filters, setFilters] = useState<Filters>(defaultFilters)
  const [stats, setStats] = useState<AuditLogStats | null>(null)
  const [listData, setListData] = useState<AuditLogListResponse | null>(null)
  const [viewerRole, setViewerRole] = useState<'super-admin' | 'auditor' | 'manager' | 'operator'>('super-admin')
  const [viewerId, setViewerId] = useState('')
  const [page, setPage] = useState(1)
  const [limit, setLimit] = useState(10)
  const [loading, setLoading] = useState(false)
  const [statsLoading, setStatsLoading] = useState(false)
  const [exportLoading, setExportLoading] = useState(false)
  const [selectedIds, setSelectedIds] = useState<string[]>([])
  const [expandedRows, setExpandedRows] = useState<Record<string, boolean>>({})
  const [deleteModalState, setDeleteModalState] = useState<{ open: boolean; ids: string[] }>({ open: false, ids: [] })
  const [deleteLoading, setDeleteLoading] = useState(false)
  const [lastStatsUpdatedAt, setLastStatsUpdatedAt] = useState<string>('')

  const normalizedParams = useMemo(() => {
    return {
        page,
        limit,
        module: filters.module !== 'all' ? filters.module : undefined,
      operationType: filters.operationType !== 'all' ? filters.operationType : undefined,
      operatorKeyword: filters.operatorKeyword || undefined,
      targetType: filters.targetType !== 'all' ? filters.targetType : undefined,
      targetKeyword: filters.targetKeyword || undefined,
      operatorRole: filters.operatorRole !== 'all' ? filters.operatorRole : undefined,
      resultStatus: filters.resultStatus !== 'all' ? (filters.resultStatus as 'success' | 'failure') : undefined,
      riskLevel: filters.riskLevel !== 'all' ? (filters.riskLevel as 'low' | 'medium' | 'high') : undefined,
      isRead: filters.onlyUnread ? ('false' as const) : undefined,
      isAbnormal: filters.onlyAbnormal ? ('true' as const) : undefined,
      startTime: filters.startTime || undefined,
      endTime: filters.endTime || undefined,
      viewerRole,
      viewerId: viewerId || undefined,
      viewerDepartments: filters.viewerDepartments || undefined,
    }
  }, [filters, page, limit, viewerRole, viewerId])

  const baseStatsParams = useMemo(() => {
    const { page: _omitPage, limit: _omitLimit, ...rest } = normalizedParams
    void _omitPage
    void _omitLimit
    return rest
  }, [normalizedParams])

  const moduleOptions = useMemo(() => ['all', ...(listData?.aggregates?.modules ?? [])], [listData])
  const operationTypeOptions = useMemo(
    () => ['all', ...(listData?.aggregates?.operationTypes ?? ['create', 'update', 'delete', 'review', 'config', 'export', 'import'])],
    [listData]
  )
  const targetTypeOptions = useMemo(() => ['all', ...(listData?.aggregates?.targetTypes ?? [])], [listData])

  const handleFilterChange = (key: keyof Filters, value: string | boolean) => {
    setFilters((prev) => ({
      ...prev,
      [key]: value,
    }))
    setPage(1)
    setSelectedIds([])
  }

  const handleResetFilters = () => {
    setFilters(defaultFilters)
    setPage(1)
  }

  const fetchLogs = useCallback(async () => {
    setLoading(true)
    try {
      const response = await auditLogAPI.getList(normalizedParams)
      if (response.data) {
        setListData(response.data)
        setSelectedIds([])
      }
    } catch (error) {
      console.error('获取审计日志失败', error)
    } finally {
      setLoading(false)
    }
  }, [normalizedParams])

  const fetchStats = useCallback(async () => {
    setStatsLoading(true)
    try {
      const response = await auditLogAPI.getStats(baseStatsParams)
      if (response.data) {
        setStats(response.data)
        setLastStatsUpdatedAt(new Date().toISOString())
      }
    } catch (error) {
      console.error('获取审计统计失败', error)
    } finally {
      setStatsLoading(false)
    }
  }, [baseStatsParams])

  useEffect(() => {
    fetchLogs()
  }, [fetchLogs])

  useEffect(() => {
    fetchStats()
  }, [fetchStats])

  useEffect(() => {
    const interval = window.setInterval(() => {
      fetchStats()
    }, 15000)

    return () => {
      window.clearInterval(interval)
    }
  }, [fetchStats])

  const getRowId = useCallback(
    (log: AuditLogRecord, index: number) => {
      return (
        log._id ||
        [log.module || 'unknown-module', log.operationTime || log.createdAt || 'unknown-time', index]
          .join('-')
      )
    },
    []
  )

  const handleSelectAll = (event: React.ChangeEvent<HTMLInputElement>) => {
    if (!listData?.list) return
    if (event.target.checked) {
      const currentIds = listData.list
        .map((item, index) => getRowId(item, index))
        .filter(Boolean)
      setSelectedIds(currentIds)
    } else {
      setSelectedIds([])
    }
  }

  const handleSelectRow = (id: string, checked: boolean) => {
    if (!id) return
    setSelectedIds((prev) => (checked ? Array.from(new Set([...prev, id])) : prev.filter((item) => item !== id)))
  }

  const toggleExpandRow = (id: string) => {
    setExpandedRows((prev) => ({
      ...prev,
      [id]: !prev[id],
    }))
  }

  const handleMarkAsRead = async (ids: string[]) => {
    if (!ids.length) return
    try {
      await auditLogAPI.markRead({ ids, isRead: true })
    fetchLogs()
      fetchStats()
    } catch (error) {
      console.error('标记已读失败', error)
    }
  }

  const closeDeleteModal = () => {
    setDeleteModalState({ open: false, ids: [] })
  }

  const handleBatchDelete = async () => {
    const ids = deleteModalState.ids
    if (!ids.length) return
    setDeleteLoading(true)
    try {
      // 批量删除：逐个删除（需要后端支持批量删除接口）
      // TODO: 添加批量删除 API
      alert('批量删除功能暂未实现，请使用单个删除')
      // await Promise.all(ids.map(id => auditLogAPI.delete(id)))
      // setSelectedIds([])
      // fetchLogs()
      // fetchStats()
    } catch (error) {
      console.error('批量删除日志失败', error)
    } finally {
      setDeleteLoading(false)
      closeDeleteModal()
    }
  }

  const handleExport = async (format: 'excel' | 'pdf') => {
    setExportLoading(true)
    try {
      // 获取所有符合条件的数据（不分页）
      const allLogs: AuditLogRecord[] = []
      let currentPage = 1
      let hasMore = true
      const pageSize = 100 // 每次获取100条

      while (hasMore) {
        const response = await auditLogAPI.getList({
          ...normalizedParams,
          page: currentPage,
          pageSize: pageSize,
        })

        if (response.data?.list) {
          allLogs.push(...response.data.list)
          // 如果返回的数据少于 pageSize，说明已经是最后一页
          if (response.data.list.length < pageSize || allLogs.length >= (response.data.total || 0)) {
            hasMore = false
          } else {
            currentPage++
          }
        } else {
          hasMore = false
        }
      }

      if (allLogs.length === 0) {
        alert('暂无数据可导出')
        setExportLoading(false)
        return
      }

      const { exportAuditLogsToExcel, exportAuditLogsToPDF } = await import('@/utils/export/auditLogExport')

      const filename = `audit-logs-${new Date().toISOString().slice(0, 10)}.${format === 'pdf' ? 'pdf' : 'xlsx'}`

      if (format === 'excel') {
        await exportAuditLogsToExcel(allLogs, filename)
      } else {
        await exportAuditLogsToPDF(allLogs, filename)
      }
    } catch (error) {
      console.error('导出日志失败', error)
      alert('导出失败，请重试')
    } finally {
      setExportLoading(false)
    }
  }

  const totalPages = useMemo(() => Math.max(Math.ceil((listData?.total ?? 0) / limit), 1), [listData?.total, limit])
  const currentIds = useMemo(() => {
    return (listData?.list || [])
      .map((item, index) => getRowId(item, index))
      .filter(Boolean)
  }, [getRowId, listData?.list])

  const allSelected = useMemo(
    () =>
      currentIds.length > 0 &&
      currentIds.every((id) => selectedIds.includes(id)),
    [currentIds, selectedIds]
  )

  const derivedStats = useMemo(() => {
    const records = listData?.list ?? []
    const total = stats?.total ?? listData?.total ?? records.length
    const successCount = stats?.successCount ?? records.filter((record) => record.resultStatus === 'success').length
    const failureCount = stats?.failureCount ?? records.filter((record) => record.resultStatus === 'failure').length
    const highRiskCount =
      stats?.highRiskCount ?? records.filter((record) => record.riskLevel === 'high').length
    const unprocessedAbnormalCount =
      stats?.unprocessedAbnormalCount ?? listData?.counters?.unprocessedAbnormalCount ?? 0
    const latestLog = stats?.latestLog ?? records[0] ?? null

    let successRate = 0
    if (typeof stats?.successRate === 'number') {
      const raw = stats.successRate
      successRate = raw > 1 ? raw : raw * 100
    } else if (total > 0) {
      successRate = (successCount / total) * 100
    }

    return {
      total,
      successCount,
      failureCount,
      highRiskCount,
      unprocessedAbnormalCount,
      latestLog,
      successRate,
    }
  }, [listData?.counters?.unprocessedAbnormalCount, listData?.list, listData?.total, stats])

  return (
    <div className="space-y-7 animate-fade-in">
      <div className="flex flex-col gap-2">
        <h2 className="text-2xl font-bold text-gray-900 dark:text-gray-100 transition-colors">
          审计日志中心
        </h2>
        <p className="text-sm text-gray-500 dark:text-gray-400">
          支持多维度筛选、批量操作、导出，提前预警潜在风险。
        </p>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
        <Card padding="sm" className="bg-gradient-to-br from-blue-500/10 to-blue-500/5 border-blue-100">
          <div className="flex items-center gap-3">
            <div className="p-3 bg-blue-500/20 rounded-xl text-blue-600">
              <ShieldCheck size={20} />
            </div>
            <div>
              <p className="text-sm text-gray-500">日志总量</p>
              <p className="text-xl font-semibold text-gray-800">{derivedStats.total ?? '--'}</p>
            </div>
          </div>
        </Card>
        <Card padding="sm" className="bg-gradient-to-br from-emerald-500/10 to-emerald-500/5 border-emerald-100">
          <div className="flex items-center gap-3">
            <div className="p-3 bg-emerald-500/20 rounded-xl text-emerald-600">
              <Activity size={20} />
            </div>
            <div>
              <p className="text-sm text-gray-500">成功率</p>
              <p className="text-xl font-semibold text-gray-800">
                {derivedStats.total > 0
                  ? `${Math.round((derivedStats.successRate || 0) * 10) / 10}%`
                  : '--'}
              </p>
            </div>
          </div>
        </Card>
        <Card padding="sm" className="bg-gradient-to-br from-amber-500/10 to-amber-500/5 border-amber-100">
          <div className="flex items-center gap-3">
            <div className="p-3 bg-amber-500/20 rounded-xl text-amber-600">
              <Clock size={20} />
            </div>
            <div>
              <p className="text-sm text-gray-500">最新操作</p>
              <p className="text-xs text-gray-700 break-all">
                {derivedStats.latestLog
                  ? formatDateTime(derivedStats.latestLog.operationTime || derivedStats.latestLog.createdAt)
                  : '--'}
              </p>
            </div>
          </div>
        </Card>
        <Card padding="sm" className="bg-gradient-to-br from-red-500/10 to-red-500/5 border-red-100">
          <div className="flex items-center gap-3">
            <div className="p-3 bg-red-500/20 rounded-xl text-red-600">
              <AlertTriangle size={20} />
            </div>
            <div>
              <p className="text-sm text-gray-500">高风险未处理</p>
              <p className="text-xl font-semibold text-gray-800">{derivedStats.unprocessedAbnormalCount ?? '--'}</p>
            </div>
          </div>
        </Card>
      </div>

      <div className="flex items-center gap-2 text-xs text-gray-400">
        <span className="inline-flex h-2 w-2 animate-pulse rounded-full bg-emerald-400" />
        <span>
          {lastStatsUpdatedAt
            ? `实时监控已开启，最近同步：${formatDateTime(lastStatsUpdatedAt)}`
            : '实时监控已开启'}
        </span>
      </div>

      <Card className="dark:bg-gray-800 dark:border-gray-700">
        <div className="grid grid-cols-1 xl:grid-cols-6 gap-4 mb-4">
          <div className="xl:col-span-2">
            <Input
              label="关键词搜索"
              placeholder="操作人/对象/日志内容"
              value={filters.operatorKeyword}
              onChange={(event) => handleFilterChange('operatorKeyword', event.target.value)}
              leftIcon={<Search size={18} />}
            />
          </div>
          <div className="xl:col-span-2">
            <label className="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">
              <Filter size={16} className="inline mr-2 text-gray-500" />
              模块筛选
            </label>
            <select
              value={filters.module}
              onChange={(event) => handleFilterChange('module', event.target.value)}
              className="w-full px-4 py-2.5 border border-gray-300 dark:border-gray-600 rounded-xl bg-white dark:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500/50 focus:border-blue-400 dark:text-gray-200 transition-all duration-200"
            >
              {moduleOptions.map((item) => (
                <option key={item} value={item}>
                  {item === 'all' ? '全部模块' : item}
                </option>
              ))}
            </select>
          </div>
          <div>
            <label className="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">操作类型</label>
            <select
              value={filters.operationType}
              onChange={(event) => handleFilterChange('operationType', event.target.value)}
              className="w-full px-4 py-2.5 border border-gray-300 dark:border-gray-600 rounded-xl bg-white dark:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500/50 focus:border-blue-400 dark:text-gray-200 transition-all duration-200"
            >
              {operationTypeOptions.map((key) => (
                <option key={key} value={key}>
                  {key === 'all' ? '全部类型' : operationTypeLabels[key] || key}
                </option>
              ))}
            </select>
          </div>
          <div>
            <label className="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">角色筛选</label>
            <select
              value={filters.operatorRole}
              onChange={(event) => handleFilterChange('operatorRole', event.target.value)}
              className="w-full px-4 py-2.5 border border-gray-300 dark:border-gray-600 rounded-xl bg-white dark:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500/50 focus:border-blue-400 dark:text-gray-200 transition-all duration-200"
            >
              {[
                { key: 'all', label: '全部角色' },
                { key: 'super-admin', label: '超级管理员' },
                { key: 'manager', label: '运营经理' },
                { key: 'auditor', label: '审计专员' },
                { key: 'operator', label: '普通运营' },
              ].map((item) => (
                <option key={item.key} value={item.key}>
                  {item.label}
                </option>
              ))}
            </select>
          </div>
          <div>
            <label className="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">对象类型</label>
            <select
              value={filters.targetType}
              onChange={(event) => handleFilterChange('targetType', event.target.value)}
              className="w-full px-4 py-2.5 border border-gray-300 dark:border-gray-600 rounded-xl bg-white dark:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500/50 focus:border-blue-400 dark:text-gray-200 transition-all duration-200"
            >
              {targetTypeOptions.map((item) => (
                <option key={item} value={item}>
                  {item === 'all' ? '全部对象' : item}
                </option>
              ))}
            </select>
          </div>
          <div>
            <label className="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">风险等级</label>
            <select
              value={filters.riskLevel}
              onChange={(event) => handleFilterChange('riskLevel', event.target.value)}
              className="w-full px-4 py-2.5 border border-gray-300 dark:border-gray-600 rounded-xl bg-white dark:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500/50 focus:border-blue-400 dark:text-gray-200 transition-all duration-200"
            >
              {['all', 'low', 'medium', 'high'].map((key) => (
                <option key={key} value={key}>
                  {key === 'all' ? '全部' : key === 'low' ? '低风险' : key === 'medium' ? '中风险' : '高风险'}
                </option>
              ))}
            </select>
          </div>
          <div>
            <label className="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">操作结果</label>
            <select
              value={filters.resultStatus}
              onChange={(event) => handleFilterChange('resultStatus', event.target.value)}
              className="w-full px-4 py-2.5 border border-gray-300 dark:border-gray-600 rounded-xl bg-white dark:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500/50 focus:border-blue-400 dark:text-gray-200 transition-all duration-200"
            >
              {['all', 'success', 'failure'].map((key) => (
                <option key={key} value={key}>
                  {key === 'all' ? '全部' : key === 'success' ? '成功' : '失败'}
                </option>
              ))}
            </select>
          </div>
          <div>
            <Input
              label="对象关键词"
              placeholder="订单/商品/用户关键词"
              value={filters.targetKeyword}
              onChange={(event) => handleFilterChange('targetKeyword', event.target.value)}
            />
          </div>
            <div>
            <Input
                type="date"
              label="开始日期"
              value={filters.startTime}
              max={filters.endTime || undefined}
              onChange={(event) => handleFilterChange('startTime', event.target.value)}
              />
            </div>
            <div>
            <Input
                type="date"
              label="结束日期"
              value={filters.endTime}
              min={filters.startTime || undefined}
              onChange={(event) => handleFilterChange('endTime', event.target.value)}
            />
          </div>
          <div>
            <Input
              label="查看角色"
              value={viewerRole}
              onChange={(event) => setViewerRole(event.target.value as typeof viewerRole)}
              helperText="用于模拟不同权限视角的日志范围"
            />
          </div>
          <div>
            <Input
              label="查看人ID"
              value={viewerId}
              onChange={(event) => setViewerId(event.target.value)}
              placeholder="可选：当前登录用户ID"
              />
            </div>
          <div>
            <Input
              label="部门范围"
              value={filters.viewerDepartments}
              onChange={(event) => handleFilterChange('viewerDepartments', event.target.value)}
              placeholder="多部门用逗号分隔"
            />
          </div>
        </div>

        <div className="flex flex-wrap items-center gap-4 text-sm text-gray-600 mb-6">
          <label className="inline-flex items-center gap-2">
            <input
              type="checkbox"
              className="rounded border-gray-300"
              checked={filters.onlyUnread}
              onChange={(event) => handleFilterChange('onlyUnread', event.target.checked)}
            />
            仅查看未读
          </label>
          <label className="inline-flex items-center gap-2">
            <input
              type="checkbox"
              className="rounded border-gray-300"
              checked={filters.onlyAbnormal}
              onChange={(event) => handleFilterChange('onlyAbnormal', event.target.checked)}
            />
            仅查看异常
          </label>
        </div>

        <div className="flex flex-wrap items-center gap-3 mb-6">
          <Button variant="outline" size="sm" onClick={handleResetFilters}>
            清空筛选
          </Button>
          <Button variant="primary" size="sm" onClick={() => { fetchLogs(); fetchStats() }} loading={loading || statsLoading}>
            <RefreshCw size={16} className="mr-2" />
            刷新数据
          </Button>
          <Button variant="secondary" size="sm" onClick={() => handleExport('excel')} loading={exportLoading}>
            <Download size={16} className="mr-2" />
            导出 Excel
          </Button>
          <Button variant="secondary" size="sm" onClick={() => handleExport('pdf')} loading={exportLoading}>
            <Download size={16} className="mr-2" />
            导出 PDF
          </Button>
          <Button
            variant="primary"
            size="sm"
            disabled={!selectedIds.length}
            onClick={() => handleMarkAsRead(selectedIds)}
          >
            批量标记已读 ({selectedIds.length})
          </Button>
          <Button
            variant="danger"
            size="sm"
            disabled={!selectedIds.length}
            onClick={() => {
              if (!selectedIds.length) return
              setDeleteModalState({ open: true, ids: selectedIds })
            }}
          >
            批量删除 ({selectedIds.length})
          </Button>
        </div>

        <div className="overflow-x-auto border border-gray-100 dark:border-gray-700 rounded-2xl">
          <table className="min-w-full divide-y divide-gray-100 dark:divide-gray-700">
            <thead className="bg-white dark:bg-gray-800/70 text-gray-700 dark:text-gray-100 transition-colors">
              <tr>
                <th className="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider w-12">
                  <input
                    type="checkbox"
                    checked={allSelected}
                    onChange={handleSelectAll}
                    className="rounded border-gray-300"
                  />
                </th>
                <th className="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider">时间</th>
                <th className="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider">操作人</th>
                <th className="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider">模块/类型</th>
                <th className="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider">操作对象</th>
                <th className="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider">结果</th>
                <th className="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider">风险</th>
                <th className="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider">状态</th>
                <th className="px-4 py-3 text-right text-xs font-semibold uppercase tracking-wider">操作</th>
              </tr>
            </thead>
            <tbody className="bg-white dark:bg-gray-800/70 divide-y divide-gray-100 dark:divide-gray-700">
              {loading && (
                <tr>
                  <td colSpan={9} className="px-4 py-10 text-center text-sm text-gray-500">
                    正在加载数据，请稍候...
                  </td>
                </tr>
              )}
              {!loading && listData?.list.length === 0 && (
                <tr>
                  <td colSpan={9} className="px-4 py-10 text-center text-sm text-gray-500">
                    暂无符合条件的审计日志记录
                  </td>
                </tr>
              )}
              {!loading &&
                listData?.list.map((log, index) => {
                  const rowId = getRowId(log, index)
                  return (
                  <React.Fragment key={rowId}>
                    <tr className="hover:bg-blue-500/15 dark:hover:bg-blue-400/15 transition-colors">
                      <td className="px-4 py-4">
                        {rowId ? (
                          <input
                            type="checkbox"
                            checked={selectedIds.includes(rowId)}
                            onChange={(event) => handleSelectRow(rowId, event.target.checked)}
                            className="rounded border-gray-300"
                          />
                        ) : (
                          <span className="inline-block w-4 h-4 rounded border border-gray-300" />
                        )}
                      </td>
                      <td className="px-4 py-4 text-sm text-gray-600 whitespace-nowrap">
                        {formatDateTime(log.operationTime || log.createdAt)}
                        <div className="text-xs text-gray-400">IP：{log.ipAddress || '未知'}</div>
                      </td>
                    <td className="px-4 py-4">
                      <div className="flex flex-col">
                          <span className="text-sm font-semibold text-gray-800 dark:text-gray-200">
                            {log.operatorName || log.operatorAccount || '匿名用户'}
                          </span>
                          <span className="text-xs text-gray-400">角色：{log.operatorRole || '未知'}</span>
                      </div>
                    </td>
                      <td className="px-4 py-4 text-sm text-gray-700 dark:text-gray-200 space-y-2">
                      <span className="inline-flex items-center px-2.5 py-1 rounded-full text-xs font-medium bg-blue-50 text-blue-600 border border-blue-100">
                        {log.module || '通用模块'}
                      </span>
                        <div className="text-xs text-blue-500">
                          {operationTypeLabels[log.operationType] || log.operationType}
                        </div>
                      </td>
                      <td className="px-4 py-4 text-sm text-gray-700 dark:text-gray-200">
                        <div className="font-medium">{log.targetName || '--'}</div>
                        <div className="text-xs text-gray-400">{log.targetType || '未指定对象'}</div>
                    </td>
                      <td className="px-4 py-4 text-sm">
                        <div className={`font-semibold ${resultStatusStyles[log.resultStatus]}`}>
                          {log.resultStatus === 'success' ? '成功' : '失败'}
                        </div>
                        {log.resultMessage && (
                          <div className="text-xs text-gray-500">{log.resultMessage}</div>
                        )}
                      </td>
                      <td className="px-4 py-4 text-sm space-y-2">
                        <span className={`inline-flex px-2.5 py-1 rounded-full text-xs font-medium ${riskLevelStyles[log.riskLevel || 'low']}`}>
                          {log.riskLevel === 'high' ? '高风险' : log.riskLevel === 'medium' ? '中风险' : '低风险'}
                        </span>
                        {log.riskReason && <div className="text-xs text-gray-500">{log.riskReason}</div>}
                      </td>
                      <td className="px-4 py-4 text-sm text-gray-600">
                        <div className="flex flex-col gap-1">
                          <span className="inline-flex items-center gap-1 text-xs text-gray-500">
                            <Users size={12} /> {log.isRead ? '已读' : '未读'}
                          </span>
                          <span className="inline-flex items-center gap-1 text-xs text-gray-500">
                            <AlertTriangle size={12} color={log.isAbnormal ? '#f97316' : '#94a3b8'} />
                            {log.isAbnormal ? '异常待处理' : '正常'}
                          </span>
                        </div>
                      </td>
                      <td className="px-4 py-4 text-sm text-right">
                        <div className="flex items-center justify-end gap-2">
                          <Button
                            variant="outline"
                            size="sm"
                            onClick={() => toggleExpandRow(rowId)}
                          >
                            详情
                          </Button>
                          {!log.isRead && (
                            <Button
                              variant="primary"
                              size="sm"
                              onClick={() => handleMarkAsRead([log._id])}
                            >
                              标记已读
                            </Button>
                        )}
                      </div>
                    </td>
                    </tr>
                    {expandedRows[rowId] && (
                      <tr className="bg-gray-50/60 dark:bg-gray-900/40">
                        <td colSpan={9} className="px-6 py-5">
                          <div className="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm text-gray-700 dark:text-gray-200">
                            <div>
                              <h4 className="font-semibold mb-2 flex items-center gap-2 text-gray-800">
                                <CheckCircle2 size={16} className="text-emerald-500" /> 操作前内容
                              </h4>
                              <pre className="max-h-52 overflow-auto bg-white dark:bg-gray-950/50 border border-gray-100 dark:border-gray-800 rounded-xl p-3 text-xs text-gray-600 dark:text-gray-300">
                                {stringifyData(log.beforeData) || '—'}
                              </pre>
                            </div>
                            <div>
                              <h4 className="font-semibold mb-2 flex items-center gap-2 text-gray-800">
                                <Target size={16} className="text-blue-500" /> 操作后内容
                              </h4>
                              <pre className="max-h-52 overflow-auto bg-white dark:bg-gray-950/50 border border-gray-100 dark:border-gray-800 rounded-xl p-3 text-xs text-gray-600 dark:text-gray-300">
                                {stringifyData(log.afterData) || '—'}
                              </pre>
                            </div>
                            <div>
                              <h4 className="font-semibold mb-2 flex items-center gap-2 text-gray-800">
                                <Mail size={16} className="text-indigo-500" /> 元数据与标签
                              </h4>
                              <div className="space-y-2 text-xs text-gray-600 dark:text-gray-300">
                                <div>关联标签：{log.tags?.length ? log.tags.join('、') : '—'}</div>
                                <div>链路ID：{log.chainId || '—'}</div>
                                <div>关联ID：{log.correlationId || '—'}</div>
                                <div className="bg-white dark:bg-gray-950/50 border border-gray-100 dark:border-gray-800 rounded-xl p-3 whitespace-pre-wrap">
                                  {stringifyData(log.metadata) || '无更多信息'}
                                </div>
                              </div>
                            </div>
                          </div>
                    </td>
                  </tr>
                    )}
                  </React.Fragment>
                )})}
            </tbody>
          </table>
        </div>

        <div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4 mt-6">
          <div className="flex items-center gap-2 text-sm text-gray-500">
            <span>每页显示</span>
            <select
              value={limit}
              onChange={(event) => {
                setLimit(Number(event.target.value))
                setPage(1)
              }}
              className="px-3 py-1.5 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 focus:outline-none text-sm"
            >
              {[10, 20, 50].map((size) => (
                <option key={size} value={size}>
                  {size}
                </option>
              ))}
            </select>
            <span>
              条，当前第 {page}/{totalPages} 页，共 {listData?.total ?? 0} 条记录
            </span>
          </div>
          <div className="flex items-center gap-3">
            <Button variant="outline" size="sm" onClick={() => setPage((prev) => Math.max(prev - 1, 1))} disabled={page === 1}>
              上一页
            </Button>
            <Button
              variant="outline"
              size="sm"
              onClick={() => setPage((prev) => Math.min(prev + 1, totalPages))}
              disabled={page === totalPages}
            >
              下一页
            </Button>
          </div>
        </div>
      </Card>

      <Modal
        isOpen={deleteModalState.open}
        onClose={closeDeleteModal}
        title="批量删除审计日志"
        size="md"
      >
        <div className="space-y-6">
          <div className="flex items-start gap-4 rounded-2xl border border-red-100 bg-red-50/80 p-4 dark:border-red-500/30 dark:bg-red-500/10">
            <div className="mt-0.5 shrink-0 rounded-full bg-red-500/20 p-2 text-red-600 dark:text-red-400">
              <AlertTriangle size={24} />
            </div>
            <div className="space-y-2 text-sm leading-relaxed">
              <p className="text-base font-semibold text-red-600 dark:text-red-400">
                即将删除 {deleteModalState.ids.length} 条审计日志记录
              </p>
              <p className="text-gray-700 dark:text-gray-300">
                删除操作不可撤销，将永久移除所选日志及其关联的风险评估、链路追踪数据。建议先导出备份，再执行删除。
              </p>
            </div>
            </div>

          <div className="rounded-2xl border border-gray-100 bg-white/80 p-4 text-sm dark:border-gray-700/60 dark:bg-gray-900/40">
            <h4 className="mb-3 text-sm font-semibold text-gray-900 dark:text-gray-100">删除前请确认：</h4>
            <ul className="space-y-2 text-gray-600 dark:text-gray-300">
              <li>• 所选日志均不再用于合规、审计或风控追踪</li>
              <li>• 已与业务及安全团队确认数据清理窗口</li>
              <li>• 若需保留，可先通过“导出”功能生成存档</li>
            </ul>
      </div>

          <div className="flex items-center justify-end gap-3 border-t border-gray-100 pt-4 dark:border-gray-700/60">
            <Button variant="outline" size="sm" onClick={closeDeleteModal} disabled={deleteLoading}>
              暂不删除
          </Button>
            <Button variant="danger" size="sm" loading={deleteLoading} onClick={handleBatchDelete}>
              确认删除
                  </Button>
                </div>
              </div>
      </Modal>
    </div>
  )
}

export default AuditLog

